package org.project.d.register.nacos;

import com.alibaba.boot.nacos.discovery.autoconfigure.AutoRegisterException;
import com.alibaba.boot.nacos.discovery.properties.NacosDiscoveryProperties;
import com.alibaba.boot.nacos.discovery.properties.Register;
import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import org.apache.commons.lang3.StringUtils;
import org.project.d.network.utils.NetUtils;
import org.project.d.starter.network.ProjectNetworkAutoRegister;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutionException;

/**
 * @author lin
 * @version V1.0
 * @description
 * @date 2020/9/21 5:14 下午
 */
@Component
public class NacosDiscoveryAutoRegister implements ApplicationListener<ApplicationReadyEvent> {
    private static final Logger logger = LoggerFactory
            .getLogger(NacosDiscoveryAutoRegister.class);

    @NacosInjected
    private NamingService namingService;

    @Autowired
    private NacosDiscoveryProperties discoveryProperties;
    @Autowired
    private ProjectNetworkAutoRegister projectNetworkAutoRegister;
    @Value("${spring.application.name:}")
    private String applicationName;
    @Autowired
    private RegisterServer registerServer;

    public RegisterServer getRegisterServer() {
        return registerServer;
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {

        if (!discoveryProperties.isAutoRegister()) {
            return;
        }

        Register tcpRegister = discoveryProperties.getRegister();
//      根据serverStartResult进行服务注册
        ProjectNetworkAutoRegister.ServerStartResult serverStartResult = projectNetworkAutoRegister.getServerStartResult();
        if (StringUtils.isEmpty(tcpRegister.getIp())) {
            tcpRegister.setIp(NetUtils.getLocalAddressString());
        }
        try {
            if (serverStartResult.isUdpStart()) {
                Register udpRegister = new Register();
                BeanUtils.copyProperties(tcpRegister, udpRegister);
                if (StringUtils.isNotBlank(serverStartResult.getUdpHost())) {
                    udpRegister.setIp(serverStartResult.getUdpHost());
                }
                if (serverStartResult.getUdpPort() != 0) {
                    udpRegister.setPort(serverStartResult.getUdpPort());
                }
                if (StringUtils.isNotBlank(serverStartResult.getUdpServerName())) {
                    udpRegister.setServiceName(serverStartResult.getUdpServerName());
                }
                if (udpRegister.getPort() == 0) {
                    udpRegister.setPort(8080);
                    logger.warn("please set udpRegister port tmp port: 8080");
                }
                String udpServerTail = "-udp";
                if (StringUtils.isNotBlank(udpRegister.getServiceName()) && !StringUtils.endsWithIgnoreCase(udpRegister.getServiceName(), udpServerTail)) {
                    udpRegister.setServiceName(udpRegister.getServiceName() + udpServerTail);
                }
                udpRegister.getMetadata().put("preserved.udpRegister.source", "SPRING_BOOT");
                udpRegister.setInstanceId("");
                if (serverStartResult.getUdpStartEnd().get()) {
                    namingService.registerInstance(udpRegister.getServiceName(), udpRegister.getGroupName(),
                            udpRegister);
                    logger.info("Finished auto udpRegister service : {}, ip : {}, port : {}",
                            udpRegister.getServiceName(), udpRegister.getIp(), udpRegister.getPort());
                }
                registerServer.setUdpRegister(udpRegister);
            }
            if (serverStartResult.isTcpStart()) {
                if (StringUtils.isNotBlank(serverStartResult.getTcpHost())) {
                    tcpRegister.setIp(serverStartResult.getTcpHost());
                }
                if (serverStartResult.getTcpPort() != 0) {
                    tcpRegister.setPort(serverStartResult.getTcpPort());
                }
                if (StringUtils.isNotBlank(serverStartResult.getTcpServerName())) {
                    tcpRegister.setServiceName(serverStartResult.getTcpServerName());
                }
                if (tcpRegister.getPort() == 0) {
                    tcpRegister.setPort(8080);
                    logger.warn("please set tcpRegister port tmp port: 8080");
                }
                tcpRegister.getMetadata().put("preserved.tcpRegister.source", "SPRING_BOOT");
                tcpRegister.setInstanceId("");
                if (serverStartResult.getTcpStartEnd().get()) {
                    namingService.registerInstance(tcpRegister.getServiceName(), tcpRegister.getGroupName(),
                            tcpRegister);
                    logger.info("Finished auto tcpRegister service : {}, ip : {}, port : {}",
                            tcpRegister.getServiceName(), tcpRegister.getIp(), tcpRegister.getPort());
                }
                registerServer.setTcpRegister(tcpRegister);
            }
        } catch (InterruptedException | NacosException | ExecutionException e) {
            throw new AutoRegisterException(e);
        }
    }
}
